home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / apache / bin / apxs.pl < prev    next >
Perl Script  |  2006-08-13  |  25KB  |  799 lines

  1. #!C:\xampp\perl\bin\perl.EXE -w
  2. # ====================================================================
  3. #
  4. #  Copyright 2003-2004  The Apache Software Foundation
  5. #
  6. #  Licensed under the Apache License, Version 2.0 (the "License");
  7. #  you may not use this file except in compliance with the License.
  8. #  You may obtain a copy of the License at
  9. #
  10. #      http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. #  Unless required by applicable law or agreed to in writing, software
  13. #  distributed under the License is distributed on an "AS IS" BASIS,
  14. #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. #  See the License for the specific language governing permissions and
  16. #  limitations under the License.
  17.  
  18. # apxs script designed to allow easy command line access to Apache
  19. # configuration parameters.
  20.  
  21. require 5.003;
  22. use strict;
  23. package apxs;
  24. use File::Copy;
  25. use File::Spec::Functions;
  26.  
  27. ##
  28. ##  Configuration
  29. ##
  30.  
  31. my %config_vars = ();
  32.  
  33. my $installbuilddir = 'H:\apache\build';
  34. get_config_vars("$installbuilddir/config_vars.mk",\%config_vars);
  35.  
  36. # read the configuration variables once
  37.  
  38. my $prefix          = get_vars('prefix');
  39. my $CFG_PREFIX      = $prefix;
  40. my $exec_prefix     = get_vars('exec_prefix');
  41. my $datadir         = get_vars('datadir');
  42. my $localstatedir   = get_vars('localstatedir');
  43. my $CFG_TARGET      = get_vars('progname');
  44. my $progname        = get_vars('progname');
  45. my $CFG_SYSCONFDIR  = get_vars('sysconfdir');
  46. my $CFG_SYSCONF     = get_vars('sysconf');
  47. my $CFG_CFLAGS      = join ' ', map { get_vars($_) }
  48.     qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
  49. my $includedir      = get_vars('includedir');
  50. my $CFG_INCLUDEDIR  = $includedir;
  51. my $libdir          = get_vars('libdir');
  52. my $CFG_LIBDIR      = $libdir;
  53. my $CFG_CC          = get_vars('CC');
  54. my $CFG_LD          = get_vars('LD');
  55. my $CFG_LDFLAGS     = get_vars('LDFLAGS');
  56. my $libexecdir      = get_vars('libexecdir');
  57. my $CFG_LIBEXECDIR  = $libexecdir;
  58. my $sbindir         = get_vars('sbindir');
  59. my $CFG_SBINDIR     = $sbindir;
  60. my $ltflags         = $ENV{LTFLAGS};
  61. my $apr_libname     = get_vars('APR_LIBNAME');
  62. my $aprutil_libname = get_vars('APRUTIL_LIBNAME');
  63.  
  64. $ltflags or $ltflags = '--silent';
  65.  
  66. my %internal_vars = map {$_ => 1}
  67.     qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB
  68.        PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR SYSCONF);
  69.  
  70. my $CP    = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e cp';
  71. my $CHMOD = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e chmod';
  72. my $RM_F  = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e rm_f';
  73. my $TOUCH = 'C:\xampp\perl\bin\perl.EXE -MExtUtils::Command -e touch';
  74.  
  75. ##
  76. ##  parse argument line
  77. ##
  78.  
  79. #   defaults for parameters
  80. my $opt_n = '';
  81. my $opt_g = '';
  82. my $opt_c = 0;
  83. my $opt_o = '';
  84. my @opt_D = ();
  85. my @opt_I = ();
  86. my @opt_L = ();
  87. my @opt_l = ();
  88. my @opt_W = ();
  89. my @opt_S = ();
  90. my $opt_e = 0;
  91. my $opt_i = 0;
  92. my $opt_a = 0;
  93. my $opt_A = 0;
  94. my $opt_q = 0;
  95. my $opt_h = 0;
  96. my $opt_p = 0;
  97. my $opt_d = 0;
  98.  
  99. #   this subroutine is derived from Perl's getopts.pl with the enhancement of
  100. #   the "+" metacharacter at the format string to allow a list to be built by
  101. #   subsequent occurrences of the same option.
  102. sub Getopts {
  103.     my ($argumentative, @ARGV) = @_;
  104.     my $errs = 0;
  105.     local $_;
  106.     local $[ = 0;
  107.  
  108.     my @args = split / */, $argumentative;
  109.     while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
  110.         my ($first, $rest) = ($1,$2);
  111.         if ($_ =~ m|^--$|) {
  112.             shift @ARGV;
  113.             last;
  114.         }
  115.         my $pos = index($argumentative,$first);
  116.         if ($pos >= $[) {
  117.             if ($pos < $#args && $args[$pos+1] eq ':') {
  118.                 shift @ARGV;
  119.                 if ($rest eq '') {
  120.                     unless (@ARGV) {
  121.                         error("Incomplete option: $first (needs an argument)");
  122.                         $errs++;
  123.                     }
  124.                     $rest = shift(@ARGV);
  125.                 }
  126.                 eval "\$opt_$first = \$rest;";
  127.             }
  128.             elsif ($pos < $#args && $args[$pos+1] eq '+') {
  129.                 shift @ARGV;
  130.                 if ($rest eq '') {
  131.                     unless (@ARGV) {
  132.                         error("Incomplete option: $first (needs an argument)");
  133.                         $errs++;
  134.                     }
  135.                     $rest = shift(@ARGV);
  136.                 }
  137.                 eval "push(\@opt_$first, \$rest);";
  138.             }
  139.             else {
  140.                 eval "\$opt_$first = 1";
  141.                 if ($rest eq '') {
  142.                     shift(@ARGV);
  143.                 }
  144.                 else {
  145.                     $ARGV[0] = "-$rest";
  146.                 }
  147.             }
  148.         }
  149.         else {
  150.             error("Unknown option: $first");
  151.             $errs++;
  152.             if ($rest ne '') {
  153.                 $ARGV[0] = "-$rest";
  154.             }
  155.             else {
  156.                 shift(@ARGV);
  157.             }
  158.         }
  159.     }
  160.     return ($errs == 0, @ARGV);
  161. }
  162.  
  163. sub usage {
  164.     print STDERR <<'END';
  165. Usage: apxs -g [-S <var>=<val>] -n <modname>
  166.        apxs -q [-S <var>=<val>] <query> ...
  167.        apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]
  168.                [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]
  169.                [-Wl,<flags>] [-p] <files> ...
  170.        apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
  171.        apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
  172.  
  173. END
  174.     exit(1);
  175. }
  176.  
  177. #   option handling
  178. my $rc;
  179. ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaApd", @ARGV);
  180. &usage if ($rc == 0);
  181. &usage if ($#ARGV == -1 and not $opt_g);
  182. &usage if (not $opt_q and not ($opt_g and $opt_n) 
  183.            and not $opt_i and not $opt_c and not $opt_e);
  184.  
  185. #   argument handling
  186. my @args = @ARGV;
  187. my $name = 'unknown';
  188. $name = $opt_n if ($opt_n ne '');
  189.  
  190. if (@opt_S) {
  191.     my ($opt_S);
  192.     foreach $opt_S (@opt_S) {
  193.         if ($opt_S =~ m/^([^=]+)=(.*)$/) {
  194.             my ($var) = $1;
  195.             my ($val) = $2;
  196.             my $oldval = eval "\$CFG_$var";
  197.  
  198.             unless ($var and $oldval) {
  199.                 print STDERR "apxs:Error: no config variable $var\n";
  200.                 &usage;
  201.             }
  202.  
  203.             eval "\$CFG_${var}=\"${val}\"";
  204.         } else {
  205.             print STDERR "apxs:Error: malformatted -S option\n";
  206.             &usage;
  207.         }    
  208.     }
  209. }
  210.  
  211. ##
  212. ##  Initial shared object support check
  213. ##
  214. my $httpd = catfile get_vars("sbindir"), get_vars("progname");
  215. my $envvars = catfile get_vars("sbindir"), "envvars";
  216.  
  217. #allow apxs to be run from the source tree, before installation
  218. if ($0 =~ m:support/apxs$:) {
  219.     ($httpd = $0) =~ s:support/apxs$::;
  220. }
  221.  
  222. unless (-f $httpd) {
  223.     error("$httpd not found or not executable");
  224.     exit 1;
  225. }
  226.  
  227. sub get_config_vars{
  228.     my ($file, $rh_config) = @_;
  229.  
  230.     open IN, $file or die "cannot open $file: $!";
  231.     while (<IN>){
  232.         if (/^\s*(.*?)\s*=\s*(.*)$/){
  233.             $rh_config->{$1} = $2;
  234.         }
  235.     }
  236.     close IN;
  237. }
  238.  
  239. sub get_vars {
  240.     my $result = '';
  241.     my $ok = 0;
  242.     my $arg;
  243.     foreach $arg (@_) {
  244.         if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) {
  245.             my $val = exists $config_vars{$arg}
  246.                 ? $config_vars{$arg}
  247.                     : $config_vars{lc $arg};
  248.             $val =~ s/[()]//g;
  249.             $result .= $val if defined $val;
  250.             $result .= ";;"; 
  251.             $ok = 1;
  252.         }
  253.         if (not $ok) {
  254.             if (exists $internal_vars{$arg} 
  255.                 or exists $internal_vars{lc $arg}) {
  256.                 my $val = exists $internal_vars{$arg} ? $arg : lc $arg;
  257.                 $val = eval "\$CFG_$val";
  258.                 $result .= $val if defined $val;
  259.                 $result .= ";;";
  260.                 $ok = 1;
  261.             }
  262.             if (not $ok) {
  263.                 error("Invalid query string `$arg'");
  264.                 exit(1);
  265.             }
  266.         }
  267.     }
  268.     $result =~ s|;;$||;
  269.     #    $result =~ s|:| |;
  270.     return $result;
  271. }
  272.  
  273. ##
  274. ##  Operation
  275. ##
  276.  
  277. #   helper function for executing a list of
  278. #   system command with return code checks
  279. sub execute_cmds {
  280.     my (@cmds) = @_;
  281.     my ($cmd, $rc);
  282.  
  283.     foreach $cmd (@cmds) {
  284.         notice($cmd);
  285.         $rc = system $cmd;
  286.         if ($rc) {
  287.             error(sprintf "Command failed with rc=%d\n", $rc << 8);
  288.             exit 1 ;
  289.         }
  290.     }
  291. }
  292.  
  293. if ($opt_g) {
  294.     ##
  295.     ##  SAMPLE MODULE SOURCE GENERATION
  296.     ##
  297.  
  298.     if (-d $name) {
  299.         error("Directory `$name' already exists. Remove first");
  300.         exit(1);
  301.     }
  302.  
  303.     my $data = join('', <DATA>);
  304.     $data =~ s!__END__.*!!s;
  305.     $data =~ s|%NAME%|$name|sg;
  306.     $data =~ s|%PROGNAME%|$progname|sg;
  307.     $data =~ s|%SYSCONF%|$CFG_SYSCONF|sg;
  308.     $data =~ s|%PREFIX%|$prefix|sg;
  309.     $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg;
  310.  
  311.     my ($mkf, $src) = ($data =~ m|^(.+)-=\#=-\n(.+)|s);
  312.  
  313.     notice("Creating [DIR]  $name");
  314.     mkdir $name or die "Cannot mkdir $name: $!";
  315.     notice("Creating [FILE] $name/Makefile");
  316.     open(FP, ">${name}/Makefile") or die "Cannot open ${name}/Makefile: $!";
  317.     print FP $mkf;
  318.     close(FP);
  319.     notice("Creating [FILE] $name/mod_$name.c");
  320.     open(FP, ">${name}/mod_${name}.c") || die;
  321.     print FP $src;
  322.     close(FP);
  323.     notice("Creating [FILE] $name/.deps");
  324.     open(FP, ">${name}/.deps") or die "Cannot open ${name}/.deps: $!";
  325.     close(FP);
  326.  
  327.     exit(0);
  328. }
  329.  
  330. if ($opt_q) {
  331.     ##
  332.     ##  QUERY INFORMATION 
  333.     ##
  334.     my $result = get_vars(@args);
  335.     print "$result\n";
  336. }
  337.  
  338. my $apr_bindir = get_vars("APR_BINDIR");
  339. my $apu_bindir = get_vars("APU_BINDIR");
  340.  
  341. my $apr_includedir = qq{-I"$prefix/include"};
  342. my $apu_includedir = qq{-I$"prefix/include"};
  343.  
  344. if ($opt_c) {
  345.     ##
  346.     ##  SHARED OBJECT COMPILATION
  347.     ##
  348.     
  349.     #   split files into sources and objects
  350.     my @srcs = ();
  351.     my @objs = ();
  352.     my $f;
  353.     foreach $f (@args) {
  354.         if ($f =~ m|\.c$|) {
  355.             push(@srcs, $f);
  356.         }
  357.         else {
  358.             push(@objs, $f);
  359.         }
  360.     }
  361.  
  362.     #   determine output file
  363.     my $dso_file;
  364.     if ($opt_o eq '') {
  365.         if ($#srcs > -1) {
  366.             $dso_file = $srcs[0];
  367.             $dso_file =~ s|\.[^.]+$|.so|;
  368.         }
  369.         elsif ($#objs > -1) {
  370.             $dso_file = $objs[0];
  371.             $dso_file =~ s|\.[^.]+$|.so|;
  372.         }
  373.         else {
  374.             $dso_file = "mod_unknown.so";
  375.         }
  376.     }
  377.     else {
  378.         $dso_file = $opt_o;
  379.     }
  380.  
  381.     #   create compilation commands
  382.     my @cmds = ();
  383.     my $opt = '';
  384.     my ($opt_Wc, $opt_I, $opt_D);
  385.     foreach $opt_Wc (@opt_W) {
  386.         $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|);
  387.     }
  388.     foreach $opt_I (@opt_I) {
  389.         $opt .= qq{ /I"$opt_I" };
  390.     }
  391.     foreach $opt_D (@opt_D) {
  392.         $opt .= qq{ /D "$opt_D" };
  393.     }
  394.     my $cflags = "$CFG_CFLAGS";
  395.     if ($opt_d) {
  396.         $cflags =~ s!NDEBUG!DEBUG!;
  397.         $cflags .= ' /Zi';
  398.         $cflags =~ s!/MD !/MDd !;
  399.     }
  400.     my $s;
  401.     my $mod;
  402.     foreach $s (@srcs) {
  403.         my $slo = $s;
  404.         $slo =~ s|\.c$|.slo|;
  405.         my $lo = $s;
  406.         $lo =~ s|\.c$|.lo|;
  407.         my $la = $s;
  408.         $la =~ s|\.c$|.la|;
  409.         my $o = $s;
  410.         $o =~ s|\.c$|.o|;
  411.         push(@cmds, qq{$CFG_CC $cflags -I"$CFG_INCLUDEDIR" $opt /c /Fo$lo $s});
  412.         unshift(@objs, $lo);
  413.     }
  414.  
  415.     #   create link command
  416.     my $o;
  417.     my $lo;
  418.     $opt = '';
  419.     foreach $o (@objs) {
  420.         $lo .= " $o";
  421.     }
  422.     my ($opt_Wl, $opt_L, $opt_l);
  423.     foreach $opt_Wl (@opt_W) {
  424.         if ($CFG_CC !~ m/gcc$/) {
  425.             $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|);
  426.         } else {
  427.             $opt .= " -W$opt_Wl";
  428.         }
  429.     }
  430.     foreach $opt_L (@opt_L) {
  431.         $opt .= qq{ /libpath:"$opt_L" };
  432.     }
  433.     foreach $opt_l (@opt_l) {
  434.         $opt_l .= '.lib' unless ($opt_l =~ /\.lib$/); 
  435.         $opt .= " $opt_l";
  436.     }
  437.  
  438.     if ($opt_p == 1) {
  439.         $opt .= " ".$aprutil_libname." ".$apr_libname;
  440.     }
  441.     else {
  442.         my $apr_ldflags;
  443.         $opt .= " $apr_ldflags";
  444.     }
  445.     my $ldflags = "$CFG_LDFLAGS";
  446.     if ($opt_d) {
  447.         $ldflags .= ' /debug';
  448.     }
  449.     push(@cmds, "$CFG_LD $ldflags /out:$dso_file $opt $lo");
  450.  
  451.     #   execute the commands
  452.     &execute_cmds(@cmds);
  453.  
  454.     #   allow one-step compilation and installation
  455.     if ($opt_i or $opt_e) {
  456.         @args = ( $dso_file );
  457.     }
  458. }
  459.  
  460. if ($opt_i or $opt_e) {
  461.     ##
  462.     ##  SHARED OBJECT INSTALLATION
  463.     ##
  464.     unless (-d $CFG_LIBEXECDIR) {
  465.         die "Directory $CFG_LIBEXECDIR not found";
  466.     }
  467.     #   determine installation commands
  468.     #   and corresponding LoadModule/AddModule directives
  469.     my @lmd = ();
  470.     my @amd = ();
  471.     my @cmds = ();
  472.     my $f;
  473.     foreach $f (@args) {
  474.         my $end = qr{(\.so|\.la)$};
  475.         if ($f !~ m!$end!) {
  476.             error("file $f is not a shared object");
  477.             exit(1);
  478.         }
  479.         my $t = $f;
  480.         $t =~ s|^.+/([^/]+)$|$1|;
  481.         $t =~ s|\.la$|\.so|;
  482.         (my $libf = $f) =~ s!$end!.lib!;
  483.         (my $libt = $t) =~ s!$end!.lib!;
  484.         (my $pdbf = $f) =~ s!$end!.pdb!;
  485.         (my $pdbt = $t) =~ s!$end!.pdb!;
  486.  
  487.         if ($opt_i) {
  488.             push(@cmds, "$CP $f $CFG_LIBEXECDIR");
  489.             push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR\\$t");
  490.             if (-f $libf) {
  491.                 push(@cmds, "$CP $libf $CFG_LIBDIR");
  492.                 push(@cmds, "$CHMOD 755 $CFG_LIBDIR\\$libt");
  493.             }
  494.             if ($opt_d and -f $pdbf) {
  495.                 push(@cmds, "$CP $pdbf $CFG_LIBEXECDIR");
  496.                 push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR\\$pdbt");
  497.             }
  498.         }
  499.  
  500.         #   determine module symbolname and filename
  501.         my $filename = '';
  502.         if ($name eq 'unknown') {
  503.             $name = '';
  504.             my $base = $f;
  505.             $base =~ s|\.[^.]+$||;
  506.             if (-f "$base.c") {
  507.                 open(FP, "<$base.c");
  508.                 my $content = join('', <FP>);
  509.                 close(FP);
  510.                 if ($content =~ m|.*module\s+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
  511.                     $name = "$1";
  512.                     $filename = "$base.c";
  513.                     $filename =~ s|^[^/]+/||;
  514.                 }
  515.             }
  516.             if ($name eq '') {
  517.                 if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
  518.                     $name = "$1";
  519.                     $filename = $base;
  520.                     $filename =~ s|^[^/]+/||;
  521.                 }
  522.             }
  523.             if ($name eq '') {
  524.                 error("Sorry, cannot determine bootstrap symbol name");
  525.                 error("Please specify one with option `-n'");
  526.                 exit(1);
  527.             }
  528.         }
  529.         if ($filename eq '') {
  530.             $filename = "mod_${name}.c";
  531.         }
  532.         my $dir = $CFG_LIBEXECDIR;
  533.         $dir =~ s|^$CFG_PREFIX/?||;
  534.         $dir =~ s|(.)$|$1/|;
  535.         $dir =~ s|\\|/|g;
  536.         $t =~ s|\.la$|.so|;
  537.         push(@lmd, 
  538.              sprintf("LoadModule %-18s %s", "${name}_module", qq{"$dir$t"}));
  539.         push(@amd, sprintf("AddModule %s", $filename));
  540.     }
  541.  
  542.     #   execute the commands
  543.     &execute_cmds(@cmds);
  544.  
  545.     #   activate module via LoadModule/AddModule directive
  546.     if ($opt_a or $opt_A) {
  547.         if (not -f "$CFG_SYSCONFDIR/$CFG_SYSCONF") {
  548.             error("Config file $CFG_SYSCONFDIR/$CFG_SYSCONF not found");
  549.             exit(1);
  550.         }
  551.  
  552.         open(FP, "<$CFG_SYSCONFDIR/$CFG_SYSCONF") 
  553.             || die "Cannot open $CFG_SYSCONFDIR/$CFG_SYSCONF: $!";
  554.         my $content = join('', <FP>);
  555.         close(FP);
  556.  
  557.         if ($content !~ m|\n\#?\s*LoadModule\s+|) {
  558.             error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_SYSCONF file.");
  559.             error("At least one `LoadModule' directive already has to exist.");
  560.             exit(1);
  561.         }
  562.  
  563.         my $lmd;
  564.         my $c = '';
  565.         $c = '#' if ($opt_A);
  566.         foreach $lmd (@lmd) {
  567.             my $what = $opt_A ? "preparing" : "activating";
  568.             if ($content !~ m|\n\#?\s*$lmd|) {
  569.                 # check for open <containers>, so that the new LoadModule
  570.                 # directive always appears *outside* of an <container>.
  571.  
  572.                 my $before = 
  573.                     ($content =~ m|^(.*\n)\#?\s*LoadModule\s+[^\n]+\n|s)[0];
  574.  
  575.                 # the '()=' trick forces list context and the scalar
  576.                 # assignment counts the number of list members (aka number
  577.                 # of matches) then
  578.                 my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
  579.                 my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
  580.  
  581.                 if ($cntopen == $cntclose) {
  582.                     # fine. Last LoadModule is contextless.
  583.                     $content =~ s|^(.*\n\#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|s;
  584.                 }
  585.                 elsif ($cntopen < $cntclose) {
  586.                     error('Configuration file is not valid. There are sections'
  587.                           . ' closed before opened.');
  588.                     exit(1);
  589.                 }
  590.                 else {
  591.                     # put our cmd after the section containing the last
  592.                     # LoadModule.
  593.                     my $found =
  594.                         $content =~ s!\A (  # string and capture start
  595.                                           (?:(?:
  596.                                               ^\s*  # start of conf line with a
  597.                                               (?:[^<]|<[^/]) # directive which
  598.                                                              # does not
  599.                                                              # start with '</'
  600.                                               
  601.                                               .*(?:$)\n  # rest of the line.
  602.                                                  # the '$' is in parentheses
  603.                                                  # to avoid misinterpreting
  604.                                                  # the string "$\" as
  605.                                                  # perl variable.
  606.                                                  
  607.                                                 )* # catch as much as possible
  608.                                                    # of such lines. (including
  609.                                                    # zero)
  610.                                               
  611.                                               ^\s*</.*(?:$)\n? 
  612.                                                    # after the above, we
  613.                                                    # expect a config line with
  614.                                                    # a closing container (</)
  615.                                                        
  616.                                                       ) {$cntopen}       
  617.                                               # the whole pattern (bunch
  618.                                               # of lines that end up with
  619.                                               # a closing directive) must
  620.                                               # be repeated $cntopen
  621.                                               # times. That's it.
  622.                                               # Simple, eh? ;-)
  623.                                     
  624.                                              )  # capture end  
  625.                                            !$1$c$lmd\n!mx;  
  626.                     unless ($found) {
  627.                         error('Configuration file is not valid. There are '
  628.                               . 'sections opened and not closed.');
  629.                         exit(1);
  630.                     }
  631.                 }
  632.             }
  633.             else {
  634.                 # replace already existing LoadModule line
  635.                 $content =~ s|^(.*\n)\#?\s*$lmd[^\n]*\n|$1$c$lmd\n|s;
  636.             }
  637.             $lmd =~ m|LoadModule\s+(.+?)_module.*|;
  638.             notice("[$what module `$1' in $CFG_SYSCONFDIR\\$CFG_SYSCONF]");
  639.         } 
  640.         my $amd;
  641.         foreach $amd (@amd) {
  642.             if ($content !~ m|\n\#?\s*$amd|) {
  643.                 $content =~ s|^(.*\n\#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg;
  644.             } 
  645.             else {
  646.                 $content =~ s|^(.*\n)\#?\s*$amd[^\n]*\n|$1$c$amd\n|sg;
  647.             }
  648.         }
  649.  
  650.         if (@lmd or @amd) {
  651.             my $conf = catfile $CFG_SYSCONFDIR, $CFG_SYSCONF;
  652.             my $conf_new = $conf . '.new';
  653.             my $conf_bak = $conf . '.bak';
  654.             if (open(FP, '>', $conf_new)) {
  655.                 print FP $content;
  656.                 close(FP);
  657.                 copy($conf, $conf_bak) or
  658.                          die "Backup of $conf failed: $!";
  659.                 copy($conf_new, $conf) or
  660.                          die "Copying $conf_new to $conf failed: $!";
  661.                 unlink $conf_new or
  662.                     die "Removing $conf_new failed: $!";
  663.             } 
  664.             else {
  665.                 notice("unable to open configuration file $conf_new");
  666.             }
  667.         }
  668.     }
  669. }
  670.  
  671. sub error{
  672.     print STDERR "apxs:Error: $_[0].\n";
  673. }
  674.  
  675. sub notice{
  676.     print STDERR "$_[0]\n";
  677. }
  678.  
  679. ##EOF##
  680. __DATA__
  681. ##
  682. ##  Makefile -- Build procedure for sample %NAME% Apache module
  683. ##  Autogenerated via ``apxs -n %NAME% -g''.
  684. ##
  685.  
  686. builddir=.
  687. top_srcdir=%PREFIX%
  688. top_builddir=%PREFIX%
  689.  
  690. #   the used tools
  691. APXS=apxs
  692. APACHECTL=%PROGNAME% -k
  693.  
  694. #   additional defines, includes and libraries
  695. #DEFS=-Dmy_define=my_value
  696. #INCLUDES=-Imy/include/dir
  697. #LIBS=-Lmy/lib/dir -lmylib
  698.  
  699. #   the default target
  700. all: local-shared-build
  701.  
  702. #   install the shared object file into Apache 
  703. install: install-modules
  704.  
  705. #   cleanup
  706. clean:
  707.         -@erase mod_%NAME%.lo mod_%NAME%.ilk mod_%NAME%.so mod_%NAME%.lib mod_%NAME%.exp mod_%NAME%.pdb
  708.  
  709. #   simple test
  710. test: reload
  711.     GET http://localhost/%NAME%
  712.  
  713. #   install and activate shared object by reloading Apache to
  714. #   force a reload of the shared object file
  715. reload: install restart
  716.  
  717. #   the general Apache start/restart/stop
  718. #   procedures
  719. start:
  720.     $(APACHECTL) start
  721. restart:
  722.     $(APACHECTL) restart
  723. stop:
  724.     $(APACHECTL) stop
  725.  
  726. -=#=-
  727. /* 
  728. **  mod_%NAME%.c -- Apache sample %NAME% module
  729. **  [Autogenerated via ``apxs -n %NAME% -g'']
  730. **
  731. **  To play with this sample module first compile it into a
  732. **  DSO file and install it into Apache's modules directory 
  733. **  by running:
  734. **
  735. **    $ apxs -c -i mod_%NAME%.c
  736. **
  737. **  Then activate it in Apache's %SYSCONF% file for instance
  738. **  for the URL /%NAME% in as follows:
  739. **
  740. **    #   %SYSCONF%
  741. **    LoadModule %NAME%_module modules/mod_%NAME%.so
  742. **    <Location /%NAME%>
  743. **    SetHandler %NAME%
  744. **    </Location>
  745. **
  746. **  Then after restarting Apache via
  747. **
  748. **    $ apachectl restart
  749. **
  750. **  you immediately can request the URL /%NAME% and watch for the
  751. **  output of this module. This can be achieved for instance via:
  752. **
  753. **    $ lynx -mime_header http://localhost/%NAME% 
  754. **
  755. **  The output should be similar to the following one:
  756. **
  757. **    HTTP/1.1 200 OK
  758. **    Date: Tue, 31 Mar 1998 14:42:22 GMT
  759. **    Server: Apache/1.3.4 (Unix)
  760. **    Connection: close
  761. **    Content-Type: text/html
  762. **  
  763. **    The sample page from mod_%NAME%.c
  764. */ 
  765.  
  766. #include "httpd.h"
  767. #include "http_config.h"
  768. #include "http_protocol.h"
  769. #include "ap_config.h"
  770.  
  771. /* The sample content handler */
  772. static int %NAME%_handler(request_rec *r)
  773. {
  774.     if (strcmp(r->handler, "%NAME%")) {
  775.         return DECLINED;
  776.     }
  777.     r->content_type = "text/html";      
  778.  
  779.     if (!r->header_only)
  780.         ap_rputs("The sample page from mod_%NAME%.c\n", r);
  781.     return OK;
  782. }
  783.  
  784. static void %NAME%_register_hooks(apr_pool_t *p)
  785. {
  786.     ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE);
  787. }
  788.  
  789. /* Dispatch list for API hooks */
  790. module AP_MODULE_DECLARE_DATA %NAME%_module = {
  791.     STANDARD20_MODULE_STUFF, 
  792.     NULL,                  /* create per-dir    config structures */
  793.     NULL,                  /* merge  per-dir    config structures */
  794.     NULL,                  /* create per-server config structures */
  795.     NULL,                  /* merge  per-server config structures */
  796.     NULL,                  /* table of config file commands       */
  797.     %NAME%_register_hooks  /* register hooks                      */
  798. };
  799.